package com.bizmda.bizsip.integrator.client;

import cn.hutool.core.text.StrFormatter;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bizmda.bizsip.common.*;
import com.bizmda.bizsip.integrator.config.IntegratorServiceMapping;
import com.bizmda.bizsip.integrator.config.RabbitmqConfig;
import com.bizmda.bizsip.integrator.executor.AbstractIntegratorExecutor;
import com.bizmda.bizsip.integrator.service.SipServiceLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class DelayBizServiceClientMethod {
    private final Method method;
    private final DelayBizServiceClientProxy delayServiceClientProxy;

    private RabbitTemplate rabbitTemplate;
    private IntegratorServiceMapping integratorServiceMapping;
    private SipServiceLogService sipServiceLogService;

    public DelayBizServiceClientMethod(Method method, DelayBizServiceClientProxy delayBizServiceClientProxy) {
        this.method = method;
        this.delayServiceClientProxy = delayBizServiceClientProxy;

        if (this.rabbitTemplate == null) {
            this.rabbitTemplate = SpringUtil.getBean(RabbitTemplate.class);
        }
        if (this.integratorServiceMapping == null) {
            this.integratorServiceMapping = SpringUtil.getBean(IntegratorServiceMapping.class);
        }
        if (this.sipServiceLogService == null) {
            this.sipServiceLogService = SpringUtil.getBean(SipServiceLogService.class);
        }
    }

//    public Object execute(Object[] args) throws BizException {
////        this.doDelayService(this.delayServiceClientProxy.getBizServiceId(),this.delayServiceClientProxy.getDelayMilliseconds(), args);
//        return null;
//    }

    public Object execute(Object[] args) throws BizException{
        String serviceId = this.delayServiceClientProxy.getBizServiceId();
        int[] delayMilliseconds = this.delayServiceClientProxy.getDelayMilliseconds();
        JSONObject jsonObject = new JSONObject();
        if (this.delayServiceClientProxy.getMapperInterface().equals(BizMessageInterface.class)) {
            if (args[0] instanceof JSONObject) {
                jsonObject = (JSONObject) args[0];
            }
            else {
                jsonObject = JSONUtil.parseObj(args[0]);
            }
        }
        else {
            jsonObject.set("className", this.delayServiceClientProxy.getMapperInterface().getName());
            jsonObject.set("methodName", this.method.getName());
            jsonObject.set("params", JSONUtil.parseArray(args));
        }
        BizMessage<JSONObject> inMessage = BizUtils.bizMessageThreadLocal.get();
        inMessage.setData(jsonObject);

        AbstractIntegratorExecutor integratorService = this.integratorServiceMapping.getIntegratorService(serviceId);
        if (integratorService == null) {
            throw new BizException(BizResultEnum.INTEGRATOR_SERVICE_NOT_FOUND,
                            StrFormatter.format("聚合服务不存在:{}",serviceId));
        }
        BizMessage<JSONObject> childBizMessage = BizMessage.createChildTransaction(inMessage);

        this.sipServiceLogService.sendSuspendLog(inMessage,childBizMessage);
        Map<String,Object> map = new HashMap<>(16);
        map.put("serviceId",serviceId);
        map.put("bizmessage",childBizMessage);
        map.put("retryCount",0);
        map.put("delayMilliseconds",delayMilliseconds);
        rabbitTemplate.convertAndSend(RabbitmqConfig.DELAY_SERVICE_EXCHANGE, RabbitmqConfig.DELAY_SERVICE_ROUTING_KEY, map,
                new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) {
                        //设置消息持久化
                        message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                        message.getMessageProperties().setDelay(delayMilliseconds.length>0 ? delayMilliseconds[0]:0);
                        return message;
                    }
                });
        if (this.delayServiceClientProxy.getMapperInterface().equals(BizMessageInterface.class)) {
            return childBizMessage;
        }
        else {
            return null;
        }
    }

}
